﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace _10.reflection
{
    class Program
    {
        static void Main(string[] args)
        {
#if false
            //获取Type：typeof(T)、obj.GetType()、Type.GetType(typeName, throwOnError?, IgnoreCase?)
            {
                //var t = typeof(Program);
                var t = new Program().GetType();

                Console.WriteLine("assembly: {0}", t.Assembly);
                Console.WriteLine("attributes: {0}", t.Attributes);
                Console.WriteLine("namespace: {0}", t.Namespace);
                Console.WriteLine("baseType: {0}", t.BaseType.FullName);
                Console.WriteLine("IsAbstract: {0}", t.IsAbstract);
                Console.WriteLine("IsAnsiClass: {0}", t.IsAnsiClass);
                Console.WriteLine("IsArray: {0}", t.IsArray);
                Console.WriteLine("IsAssignableFrom: {0}", t.IsAssignableFrom(typeof(string)));
                Console.WriteLine("IsAutoClass: {0}", t.IsAutoClass);
                Console.WriteLine("IsAutoLayout: {0}", t.IsAutoLayout);
                Console.WriteLine("IsByRef: {0}", t.IsByRef);
                Console.WriteLine("IsClass: {0}", t.IsClass);
                Console.WriteLine("IsCOMObject: {0}", t.IsCOMObject);
                Console.WriteLine("IsConstructedGenericType: {0}", t.IsConstructedGenericType);
                Console.WriteLine("IsContextful: {0}", t.IsContextful);
                //Console.WriteLine("IsDefined: {0}", t.IsDefined());
                Console.WriteLine("IsEnum: {0}", t.IsEnum);
                //Console.WriteLine("IsEnumDefined: {0}", t.IsEnumDefined());
                Console.WriteLine("IsPublic: {0}", t.IsPublic);
                Console.WriteLine("IsValueType: {0}", t.IsValueType);
                //var events = t.GetEvents();
            }

            Console.WriteLine("-----------------------------");
#endif
#if false
            { //Type.GetType 是根据名字来查找类型，类似Java的Class.forName(name)，但只是查找，不加载！
                string typeName = "system.string";
                Type t = Type.GetType(typeName, false, true);
                if (t != null)
                    Console.WriteLine("found the type [{0,20}]: {1}", typeName, t.FullName);
            }
            Console.WriteLine("-----------------------------");
#endif
#if false
            { //Assembly - 程序集。可以动态加载Type，这个才是类似Java的Class.forName(name)的东西！
                //Assembly asm = Assembly.Load("这里应该是程序集的某种字符串"); //了解即可

                //再来看看怎么获取当前的程序集！注意，还有另外几个方法，略。
                var asm = Assembly.GetExecutingAssembly();
                Console.WriteLine("asm.FullName: {0}", asm.FullName);
                foreach (var _t in asm.GetTypes())
                {
                    Console.WriteLine("t.FullName: {0}", _t.FullName);
                }
            }
            Console.WriteLine("-----------------------------");
#endif
#if false
            { //关键，根据Type创建实例，并执行方法
                var t = typeof(Program);
                var obj = Activator.CreateInstance(t); //创建实例
                var m = t.GetMethod("Incr");
                var r = m.Invoke(obj, new object[] { 33 });
                Console.WriteLine("method invoke result: {0}", r);

            }
            Console.WriteLine("-----------------------------");
#endif
#if true
            { //注意，获取方法或者属性或者字段等信息时，可以使用BindingFlags来缩小查询范围，例如BindingFlags.Public|BindingFlags.Static等。
                //BindingFlags.Public;
                //BindingFlags.Static;
                MethodInfo m = typeof(string).GetMethod("Copy", BindingFlags.Public | BindingFlags.Static);
                if (m == null)
                {
                    Console.WriteLine("can not find method!");
                }
                else
                {
                    Console.WriteLine("find method: {0}", m.Name);
                }
            }
#endif

            Console.ReadKey();
        }

        public int Incr(int i)
        {
            return ++i;
        }
    }
}
